// 模块全局变量

// 记录effect的调用顺序（函数栈）
const effectStack = []

// 记录effect当前正在执行的副作用函数
let activeEffect

// 存储副作用与依赖的对应关系，关系如下：
// 一个副作用可能依赖多个响应式对象；
// 一个响应式对象可能依赖多个属性；
// 一个属性可能被多个副作用依赖；
// {
//     [target]: {  // key是响应式对象，value是Map
//         [key]: []    // key是响应式对象的属性，value是一个集合
//     }
// }
const targetMap = new WeakMap() // weakmap自动gc

export function effect(func, options = {}) {
    const effectFunc = () => {
        // func是用户定义函数，因此可能有问题
        try {
            activeEffect = effectFunc
            effectStack.unshift(activeEffect)
            return func()
        } finally {
            // 执行完成后，出栈
            effectStack.shift()
            activeEffect = effectStack[0]
        }
    }
    if (!options.lazy) {
        effectFunc()
    }

    effectFunc.scheduler = options.scheduler

    return effectFunc
}

export function track(target, key) {
    if (!activeEffect) {
        return
    }

    // 获取依赖项
    let depsMap = targetMap.get(target)
    if (!depsMap) {
        targetMap.set(target, (depsMap = new Map()))
    }

    let deps = depsMap.get(key)
    if (!deps) {
        depsMap.set(key, (deps = new Set()))
    }

    deps.add(activeEffect);
}

export function trigger(target, key) {
    const depsMap = targetMap.get(target)
    if (!depsMap) {
        // target没有被依赖
        return
    }

    const deps = depsMap.get(key)
    if (!deps) {
        // key没有被依赖
        return
    }

    // 执行依赖函数
    deps.forEach((Func) => {
        Func.scheduler ? Func.scheduler(Func) : Func()
    })
}
